const { v4: uuidv4 } = require("uuid");
const { query, withTransaction } = require("../utils/db");

/**
 * 辅助函数：获取父节点可见性设置
 */
const getParentVisibility = async (FParentId, conn) => {
  if (!FParentId) return null;

  const [parentVisibility] = await query(
    `SELECT v.FId, v.FDocId, v.FIsPublic, v.FInheritParent,
     GROUP_CONCAT(vu.FUserId) AS FVisibleUserIds
     FROM t_visibility_settings v
     LEFT JOIN t_visibility_users vu ON v.FId = vu.FVisibilityId
     WHERE v.FDocId = ?
     GROUP BY v.FId`,
    [FParentId],
    conn
  );

  return parentVisibility;
};

/**
 * 辅助函数：递归获取所有子节点 ID
 */
const getAllChildNodeIds = async (FId, conn) => {
  const ids = [FId];
  const queue = [FId];

  while (queue.length) {
    const currentId = queue.shift();
    const children = await query(
      "SELECT FId FROM t_doc_nodes WHERE FParentId = ?",
      [currentId],
      conn
    );

    for (const child of children) {
      ids.push(child.FId);
      queue.push(child.FId);
    }
  }

  return ids;
};

/**
 * 辅助函数：继承父节点的可见性设置
 */
const inheritParentVisibility = async (FDocId, FParentId, conn) => {
  const parentVisibility = await getParentVisibility(FParentId, conn);

  if (!parentVisibility) {
    await query(
      "INSERT INTO t_visibility_settings (FDocId, FIsPublic, FInheritParent) VALUES (?, 1, ?)",
      [FDocId, FParentId ? 1 : 0],
      conn
    );
    return;
  }

  const result = await query(
    "INSERT INTO t_visibility_settings (FDocId, FIsPublic, FInheritParent) VALUES (?, ?, 1)",
    [FDocId, parentVisibility.FIsPublic],
    conn
  );

  if (!parentVisibility.FIsPublic && parentVisibility.FVisibleUserIds) {
    const userIds = parentVisibility.FVisibleUserIds.split(",");
    const values = userIds.map((userId) => [result.insertId, userId]);
    await query(
      "INSERT INTO t_visibility_users (FVisibilityId, FUserId) VALUES ?",
      [values],
      conn
    );
  }
};

/**
 * 获取文档树结构（含权限过滤）
 */
exports.getDocTree = async (FSpaceId, userId, isAdmin = false) => {
  const sql = `
    SELECT 
      d.*, 
      u.FUsername AS FAuthorName,
      v.FIsPublic,
      IFNULL((SELECT 1 FROM t_visibility_users vu 
              WHERE vu.FVisibilityId = v.FId AND vu.FUserId = ? LIMIT 1), 0) AS FIsVisibleToUser
    FROM t_doc_nodes d
    LEFT JOIN t_users u ON d.FAuthorId = u.FUserId
    LEFT JOIN t_visibility_settings v ON d.FId = v.FDocId
    WHERE d.FSpaceId = ?
    ORDER BY d.FCreatedAt ASC`;

  const allNodes = await query(sql, [userId, FSpaceId]);
  const isAdminBool = isAdmin === "true";

  // 过滤出可见节点
  const filteredNodes = allNodes.filter((node) => {
    if (isAdminBool) return true;
    if (node.FIsPublic) return true;
    if (node.FIsVisibleToUser) return true;
    return false;
  });

  const nodeMap = new Map();
  filteredNodes.forEach((node) => {
    nodeMap.set(node.FId, { ...node, children: [] });
  });

  // 向上寻找最近的可见父节点
  function findVisibleParent(node) {
    let parentId = node.FParentId;
    while (parentId) {
      if (nodeMap.has(parentId)) return parentId;
      const parentNode = allNodes.find((n) => n.FId === parentId);
      if (!parentNode) break;
      parentId = parentNode.FParentId;
    }
    return null;
  }

  // 构建树
  const tree = [];

  filteredNodes.forEach((node) => {
    const currentNode = nodeMap.get(node.FId);
    const visibleParentId = findVisibleParent(node);
    if (visibleParentId && nodeMap.has(visibleParentId)) {
      nodeMap.get(visibleParentId).children.push(currentNode);
    } else {
      tree.push(currentNode);
    }
  });

  // 移除空文件夹：递归遍历所有节点
  function pruneEmptyFolders(nodes) {
    return nodes
      .map((node) => ({
        ...node,
        children: pruneEmptyFolders(node.children),
      }))
      .filter((node) => {
        if (
          node.FType === "folder" &&
          node.children.length === 0 &&
          !isAdminBool
        ) {
          return false;
        }
        return true;
      });
  }

  return pruneEmptyFolders(tree);
};

/**
 * 添加文档节点（自动继承可见性）
 */
exports.addDocNode = async ({
  FSpaceId,
  FParentId,
  FTitle,
  FType,
  FContent,
  FAuthorId,
}) => {
  return withTransaction(async (conn) => {
    const FId = uuidv4();

    await query(
      `INSERT INTO t_doc_nodes (FId, FSpaceId, FParentId, FTitle, FType, FContent, FAuthorId)
       VALUES (?, ?, ?, ?, ?, ?, ?)`,
      [
        FId,
        FSpaceId,
        FParentId || null,
        FTitle,
        FType,
        FContent || "",
        FAuthorId,
      ],
      conn
    );

    await inheritParentVisibility(FId, FParentId, conn);

    return { FId, FTitle, FType };
  });
};

/**
 * 更新文档节点
 */
exports.updateDocNode = async ({ FId, FTitle, FContent }) => {
  const updates = [];
  const params = [];

  if (FTitle !== undefined) {
    updates.push("FTitle = ?");
    params.push(FTitle);
  }

  if (FContent !== undefined) {
    updates.push("FContent = ?");
    params.push(FContent);
  }

  if (updates.length === 0) throw { status: 400, message: "无更新内容" };

  params.push(FId);
  const result = await query(
    `UPDATE t_doc_nodes SET ${updates.join(", ")} WHERE FId = ?`,
    params
  );
  if (result.affectedRows === 0) throw { status: 400, message: "节点不存在" };

  return true;
};

// 在 doc.js 中添加以下方法

/**
 * 添加文档阅读记录
 */
exports.addReadHistory = async (FDocId, FUserId) => {
  return withTransaction(async (conn) => {
    // 检查文档是否存在
    const [doc] = await query(
      "SELECT 1 FROM t_doc_nodes WHERE FId = ?",
      [FDocId],
      conn
    );
    if (!doc) throw { status: 400, message: "文档不存在" };

    // 检查是否已有记录
    const [existing] = await query(
      "SELECT FId FROM t_user_doc_history WHERE FUserId = ? AND FDocId = ?",
      [FUserId, FDocId],
      conn
    );

    if (existing) {
      // 更新已有记录的阅读时间
      await query(
        "UPDATE t_user_doc_history SET FReadAt = CURRENT_TIMESTAMP WHERE FId = ?",
        [existing.FId],
        conn
      );
    } else {
      // 插入新记录
      await query(
        "INSERT INTO t_user_doc_history (FId, FUserId, FDocId) VALUES (?, ?, ?)",
        [uuidv4(), FUserId, FDocId],
        conn
      );
    }

    // 更新文档阅读次数
    await query(
      "UPDATE t_doc_nodes SET FViews = IFNULL(FViews, 0) + 1 WHERE FId = ?",
      [FDocId],
      conn
    );

    return true;
  });
};

/**
 * 获取用户阅读历史记录
 */
exports.getUserReadHistory = async (FUserId, limit = 10) => {
  const history = await query(
    `SELECT h.FDocId, h.FReadAt, d.FTitle, d.FType, d.FContent, 
     s.FTitle AS FSpaceTitle, s.FId AS FSpaceId
     FROM t_user_doc_history h
     JOIN t_doc_nodes d ON h.FDocId = d.FId
     JOIN t_spaces s ON d.FSpaceId = s.FId
     WHERE h.FUserId = ?
     ORDER BY h.FReadAt DESC
     LIMIT ?`,
    [FUserId, limit]
  );

  return history;
};

/**
 * 删除用户阅读记录
 */
exports.deleteUserReadHistory = async (FUserId, FDocId) => {
  const result = await query(
    "DELETE FROM t_user_doc_history WHERE FUserId = ? AND FDocId = ?",
    [FUserId, FDocId]
  );
  return result.affectedRows > 0;
};

// 修改原有的 deleteDocNode 方法，在删除文档时同时删除阅读记录
exports.deleteDocNode = async (FId) => {
  return withTransaction(async (conn) => {
    const allNodeIds = await getAllChildNodeIds(FId, conn);
    if (allNodeIds.length === 0) throw { status: 400, message: "节点不存在" };

    await query(
      `DELETE vu FROM t_visibility_users vu
       JOIN t_visibility_settings vs ON vu.FVisibilityId = vs.FId
       WHERE vs.FDocId IN (?)`,
      [allNodeIds],
      conn
    );

    await query(
      `DELETE FROM t_visibility_settings WHERE FDocId IN (?)`,
      [allNodeIds],
      conn
    );

    // 新增：删除关联的阅读记录
    await query(
      `DELETE FROM t_user_doc_history WHERE FDocId IN (?)`,
      [allNodeIds],
      conn
    );

    await query(`DELETE FROM t_doc_nodes WHERE FId IN (?)`, [allNodeIds], conn);

    return true;
  });
};

/**
 * 设置文档可见性（支持继承/校验父节点）
 */
exports.setDocVisibility = async ({
  FDocId,
  FIsPublic,
  FInheritParent,
  FUserIds = [],
  FParentId = null,
}) => {
  return withTransaction(async (conn) => {
    const [doc] = await query(
      "SELECT 1 FROM t_doc_nodes WHERE FId = ?",
      [FDocId],
      conn
    );
    if (!doc) throw { status: 400, message: "文档不存在" };

    let parentVisibility = null;
    if (FParentId) {
      parentVisibility = await getParentVisibility(FParentId, conn);

      if (parentVisibility) {
        if (FInheritParent) {
          FIsPublic = parentVisibility.FIsPublic === 1;
          FUserIds = parentVisibility.FVisibleUserIds
            ? parentVisibility.FVisibleUserIds.split(",")
            : [];
        } else {
          if (parentVisibility.FIsPublic === 1 && !FIsPublic) {
            throw {
              status: 400,
              message: "父节点是公开的，子节点必须设置为公开或继承父节点设置",
            };
          } else if (parentVisibility.FIsPublic !== 1 && FIsPublic) {
            throw {
              status: 400,
              message: "父节点设置了特定用户可见，子节点不能设置为公开",
            };
          }

          const parentUserIds = parentVisibility.FVisibleUserIds
            ? parentVisibility.FVisibleUserIds.split(",")
            : [];
          const invalidUsers = FUserIds.filter(
            (userId) => !parentUserIds.includes(userId)
          );

          if (invalidUsers.length > 0) {
            throw {
              status: 400,
              message: `以下用户不在父节点可见范围内: ${invalidUsers.join(
                ", "
              )}`,
            };
          }
        }
      }
    }

    const [existing] = await query(
      "SELECT FId FROM t_visibility_settings WHERE FDocId = ?",
      [FDocId],
      conn
    );

    let visibilityId;
    if (existing) {
      visibilityId = existing.FId;
      await query(
        "UPDATE t_visibility_settings SET FIsPublic = ?, FInheritParent = ? WHERE FId = ?",
        [FIsPublic ? 1 : 0, FInheritParent ? 1 : 0, visibilityId],
        conn
      );
    } else {
      const result = await query(
        "INSERT INTO t_visibility_settings (FDocId, FIsPublic, FInheritParent) VALUES (?, ?, ?)",
        [FDocId, FIsPublic ? 1 : 0, FInheritParent ? 1 : 0],
        conn
      );
      visibilityId = result.insertId;
    }

    if (!FInheritParent && !FIsPublic) {
      await query(
        "DELETE FROM t_visibility_users WHERE FVisibilityId = ?",
        [visibilityId],
        conn
      );

      if (FUserIds.length > 0) {
        const values = FUserIds.map((userId) => [visibilityId, userId]);
        await query(
          "INSERT INTO t_visibility_users (FVisibilityId, FUserId) VALUES ?",
          [values],
          conn
        );
      }
    }

    return true;
  });
};

/**
 * 获取文档可见性配置
 */
exports.getDocVisibility = async (FDocId) => {
  const [visibility] = await query(
    `SELECT v.FId, v.FDocId, v.FIsPublic, v.FInheritParent,
     GROUP_CONCAT(vu.FUserId) AS FVisibleUserIds
     FROM t_visibility_settings v
     LEFT JOIN t_visibility_users vu ON v.FId = vu.FVisibilityId
     WHERE v.FDocId = ?
     GROUP BY v.FId`,
    [FDocId]
  );

  if (!visibility) {
    return {
      FIsPublic: false,
      FInheritParent: true,
      FVisibleUserIds: [],
    };
  }

  return {
    FIsPublic: visibility.FIsPublic === 1,
    FInheritParent: visibility.FInheritParent === 1,
    FVisibleUserIds: visibility.FVisibleUserIds
      ? visibility.FVisibleUserIds.split(",")
      : [],
  };
};
